package com.myk.game.gobangchess.signs;

import com.myk.game.gobangchess.Sign;
import com.myk.game.gobangchess.utils.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * 装饰标记，在一个个矩形范围内按照Format绘制花纹
 */
public class FigureSign extends Sign {

    private final List<Pair<Integer, Integer>> tiles; //瓦片集合，每个元素由“start"+"t"+"end”组合，start格子的左上角和end格子的右下角表示一个瓦片的矩形范围。集合元素之间用"a"拼接
    private final String color; //颜色 "#FFFFFFFF"

    private String midSideLine; //四边中点到四角的边线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
    private String midCenLine; //四边中点到正中心的内线：长度为4，上右下左，0或1来表示开关
    private String corCenLine;//四角到正中心的内线：长度为4，左上为起点顺时针，0或1来表示开关
    private String adjMidLine; //相邻两个四边中点的内连线：长度为4，左上为起点顺时针，0或1来表示开关
    private String corMidLine; //四角到对面边的中点的内连线：长度为8，左上角为起点顺时针，0或1来表示开关

    private String compCenArc; //整个瓦片矩形内切椭圆的四分之一弧：长度为4，左上为起点顺时针，0或1来表示开关
    private String cenExpArc; //以四边为对称轴的扩大矩形的且与中心点相切的四分之一弧线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
    private String corExpArc; //以四个角为正中心的扩大矩形的内切椭圆的四分之一弧：长度为4，左上为起点顺时针，0或1来表示开关
    private String corCenArc;//以四个角为正中心的中心对称矩形的四分之一弧线：长度为4，左上为起点顺时针，0或1来表示开关
    private String sideExpArc; //以四边为对称轴的扩大矩形的内切椭圆的四分之一弧线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
    private String corMidArc; //一个扩大矩形，以某个角为一边中心，那个角对面的边的中点为 扩大矩形另一相邻边的的中心 的内切椭圆的四分之一弧：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关

    private String compPoint; //整个瓦片上边角中心位置的点：长度为1，左上角开始顺时针-最后到中心点，0和1来表示开关
    private String compAngle; //整个瓦片上四个角偏内部一点和中心项四个角偏外一点的直角：长度为8，先是四个角向内左上为起点顺时针4个，然后是内部向四个角左上为起点顺时针4个，0或1来表示开关

    public FigureSign(List<Pair<Integer, Integer>> tiles, String color) {
        this.tiles = tiles;
        this.color = color;
        this.midSideLine = "-1";
        this.midCenLine = "-1";
        this.corCenLine = "-1";
        this.adjMidLine = "-1";
        this.corMidLine = "-1";
        this.compCenArc = "-1";
        this.cenExpArc = "-1";
        this.corExpArc = "-1";
        this.corCenArc = "-1";
        this.sideExpArc = "-1";
        this.corMidArc = "-1";
        this.compPoint = "-1";
        this.compAngle = "-1";
    }


    /**
     * 四边中点到四角的边线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
     */
    public FigureSign setMidSideLine(int leftTopLeft, int leftTopRight, int rightTopLeft, int rightTopRight, int rightBottomRight, int rightBottomLeft, int leftBottomRight, int leftBottomLeft) {
        this.midSideLine = "" + leftTopLeft + leftTopRight + rightTopLeft + rightTopRight + rightBottomRight + rightBottomLeft + leftBottomRight + leftBottomLeft;
        return this;
    }

    /**
     * 四边中点到正中心的内线：长度为4，上右下左，0或1来表示开关
     */
    public FigureSign setMidCenLine(int top, int right, int bottom, int left) {
        this.midCenLine = "" + top + right + bottom + left;
        return this;
    }

    /**
     * 四角到正中心的内线：长度为4，左上为起点顺时针，0或1来表示开关
     */
    public FigureSign setCorCenLine(int leftTop, int rightTop, int rightBottom, int leftBottom) {
        this.corCenLine = "" + leftTop + rightTop + rightBottom + leftBottom;
        return this;
    }

    /**
     * 相邻两个四边中点的内连线：长度为4，左上为起点顺时针，0或1来表示开关
     */
    public FigureSign setAdjMidLine(int leftTop, int rightTop, int rightBottom, int leftBottom) {
        this.adjMidLine = "" + leftTop + rightTop + rightBottom + leftBottom;
        return this;
    }

    /**
     * 四角到对面边的中点的内连线：长度为8，左上角为起点顺时针，0或1来表示开关
     */
    public FigureSign setCorMidLine(int leftTopLeft, int leftTopRight, int rightTopLeft, int rightTopRight, int rightBottomRight, int rightBottomLeft, int leftBottomRight, int leftBottomLeft) {
        this.corMidLine = "" + leftTopLeft + leftTopRight + rightTopLeft + rightTopRight + rightBottomRight + rightBottomLeft + leftBottomRight + leftBottomLeft;
        return this;
    }

    /**
     * 整个瓦片矩形内切椭圆的四分之一弧：长度为4，左上为起点顺时针，0或1来表示开关
     */
    public FigureSign setCompCenArc(int leftTop, int rightTop, int rightBottom, int leftBottom) {
        this.compCenArc = "" + leftTop + rightTop + rightBottom + leftBottom;
        return this;
    }

    /**
     * 以四边为对称轴的扩大矩形的且与中心点相切的四分之一弧线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
     */
    public FigureSign setCenExpArc(int leftTopLeft, int leftTopRight, int rightTopLeft, int rightTopRight, int rightBottomRight, int rightBottomLeft, int leftBottomRight, int leftBottomLeft) {
        this.cenExpArc = "" + leftTopLeft + leftTopRight + rightTopLeft + rightTopRight + rightBottomRight + rightBottomLeft + leftBottomRight + leftBottomLeft;
        return this;
    }

    /**
     * 以四个角为正中心的扩大矩形的内切椭圆的四分之一弧：长度为4，左上为起点顺时针，0或1来表示开关
     */
    public FigureSign setCorExpArc(int leftTop, int rightTop, int rightBottom, int leftBottom) {
        this.corExpArc = "" + leftTop + rightTop + rightBottom + leftBottom;
        return this;
    }

    /**
     * 以四个角为正中心的中心对称矩形的四分之一弧线：长度为4，左上为起点顺时针，0或1来表示开关
     */
    public FigureSign setCorCenArc(int leftTop, int rightTop, int rightBottom, int leftBottom) {
        this.corCenArc = "" + leftTop + rightTop + rightBottom + leftBottom;
        return this;
    }

    /**
     * 以四边为对称轴的扩大矩形的内切椭圆的四分之一弧线：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
     */
    public FigureSign setSideExpArc(int leftTopLeft, int leftTopRight, int rightTopLeft, int rightTopRight, int rightBottomRight, int rightBottomLeft, int leftBottomRight, int leftBottomLeft) {
        this.sideExpArc = "" + leftTopLeft + leftTopRight + rightTopLeft + rightTopRight + rightBottomRight + rightBottomLeft + leftBottomRight + leftBottomLeft;
        return this;
    }

    /**
     * 一个扩大矩形，以某个角为一边中心，那个角对面的边的中点为 扩大矩形另一相邻边的的中心 的内切椭圆的四分之一弧：长度为8，左上左半边-左上右半边-右上左半边------左下右半边-左下左半边,0或1来表示开关
     */
    public FigureSign setCorMidArc(int leftTopLeft, int leftTopRight, int rightTopLeft, int rightTopRight, int rightBottomRight, int rightBottomLeft, int leftBottomRight, int leftBottomLeft) {
        this.corMidArc = "" + leftTopLeft + leftTopRight + rightTopLeft + rightTopRight + rightBottomRight + rightBottomLeft + leftBottomRight + leftBottomLeft;
        return this;
    }

    /**
     * 整个瓦片上边角中心位置的点：长度为1，左上角开始顺时针-最后到中心点，0和1来表示开关
     */
    public FigureSign setCompPoint(int leftTop, int top, int rightTop, int right, int rightBottom, int bottom, int leftBottom, int left, int center) {
        this.compPoint = "" + leftTop + top + rightTop + right + rightBottom + bottom + leftBottom + left + center;
        return this;
    }

    /**
     * 整个瓦片上四个角偏内部一点和中心项四个角偏外一点的直角：长度为8，先是四个角向内左上为起点顺时针4个，然后是内部向四个角左上为起点顺时针4个，0或1来表示开关
     */
    public FigureSign setCompAngle(int leftTopOut, int rightTopOut, int rightBottomOut, int leftBottomOut, int leftTopIn, int rightTopIn, int rightBottomIn, int leftBottomIn) {
        this.compAngle = "" + leftTopOut + rightTopOut + rightBottomOut + leftBottomOut + leftTopIn + rightTopIn + rightBottomIn + leftBottomIn;
        return this;
    }

    @Override
    public String getSignInfo() {
        return type + "," + getTilesStr() + "," + color + "," + midSideLine + "," + midCenLine + "," + corCenLine + "," + adjMidLine + "," + corMidLine + "," + compCenArc + "," + cenExpArc + "," + corExpArc + "," + corCenArc + "," + sideExpArc + "," + corMidArc + "," + compPoint + "," + compAngle;
    }

    private String getTilesStr() {
        StringBuilder sb = new StringBuilder();
        for (Pair<Integer, Integer> tile : tiles) {
            sb.append(tile.first).append("t").append(tile.second).append("a");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static FigureSign makeSingleFigure(int index, String color) {
        List<Pair<Integer, Integer>> tiles = new ArrayList<>();
        tiles.add(new Pair<>(index, index));
        return new FigureSign(tiles, color);
    }

    public static FigureSign makeGroundFigure(int start, int end, String color) {
        List<Pair<Integer, Integer>> tiles = new ArrayList<>();
        tiles.add(new Pair<>(start, end));
        return new FigureSign(tiles, color);
    }

    public static FigureSign makeBatchSingleFigure(int[] indexes, String color) {
        List<Pair<Integer, Integer>> tiles = new ArrayList<>();
        for (int index : indexes) {
            tiles.add(new Pair<>(index, index));
        }
        return new FigureSign(tiles, color);
    }

    public static FigureSign makeBatchSingleFigure(List<Integer> indexes, String color) {
        List<Pair<Integer, Integer>> tiles = new ArrayList<>();
        for (int index : indexes) {
            tiles.add(new Pair<>(index, index));
        }
        return new FigureSign(tiles, color);
    }
}
